﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Text;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Taxonomy;

namespace SharePointOnlineCmdlets
{
    /// <summary>
    /// Hooks up an MMS field to the specified Group term and anchor
    /// </summary>
    [Cmdlet(VerbsCommon.Set, "SPOMMSField")]
    public class SetMMSField : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string Field { get; set; }

        [Parameter(Mandatory = true)]
        public string Group { get; set; }

        [Parameter(Mandatory = true)]
        public string TermSet { get; set; }

        [Parameter]
        public string Anchor { get; set; }

        protected override void ProcessRecord()
        {
            var ctx = Site.Context;
            TaxonomySession session = TaxonomySession.GetTaxonomySession(ctx);
            var defaultStore = session.GetDefaultKeywordsTermStore();
            var field = Site.RootWeb.Fields.GetByInternalNameOrTitle(Field);
            var group = defaultStore.Groups.GetByName(Group);
            var term = group.TermSets.GetByName(TermSet);
            ctx.Load(field);
            ctx.Load(defaultStore);
            ctx.Load(group);
            ctx.Load(term);
            Term anchorTerm = null;
            if (!String.IsNullOrEmpty(Anchor))
            {
                if (Anchor.Contains(";"))
                {
                    var anchors = Anchor.Split(';');
                    anchorTerm = term.Terms.GetByName(anchors[0]);
                    ctx.Load(anchorTerm);
                    ctx.ExecuteQuery();
                    foreach (var anchor in anchors.Skip(1))
                    {
                        anchorTerm = anchorTerm.Terms.GetByName(anchor);
                        ctx.Load(anchorTerm);
                        ctx.ExecuteQuery();
                    }
                }
                else
                {
                    anchorTerm = term.Terms.GetByName(Anchor);
                    ctx.Load(anchorTerm);
                }

            }

            ctx.ExecuteQuery();
            TaxonomyField taxField = new TaxonomyField(ctx, field.Path);
            taxField.SspId = defaultStore.Id;
            taxField.TermSetId = term.Id;
            taxField.TargetTemplate = string.Empty;
            if (anchorTerm != null)
            {
                taxField.AnchorId = anchorTerm.Id;
            }
            taxField.UpdateAndPushChanges(true);

            ctx.Load(taxField);
            ctx.ExecuteQuery();
            base.ProcessRecord();
        }
    }

    /// <summary>
    /// Exports all Term Sets to a specified folder in the same format used to import Term Sets in the admin portal
    /// </summary>
    [Cmdlet(VerbsData.Export, "SPOTermSets")]
    public class ExportTermSets : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string Directory { get; set; }

        protected override void ProcessRecord()
        {
            var header = @"Term Set Name,Term Set Description,LCID,Available for Tagging,Term Description,Level 1 Term,Level 2 Term,Level 3 Term,Level 4 Term,Level 5 Term,Level 6 Term,Level 7 Term";
            var ctx = (ClientContext)Site.Context;
            TaxonomySession session = TaxonomySession.GetTaxonomySession(ctx);
            var defaultStore = session.GetDefaultKeywordsTermStore();
            var groups = defaultStore.Groups;
            ctx.Load(defaultStore);
            ctx.Load(groups);
            ctx.ExecuteQuery();
            foreach (var taxgroup in groups)
            {
                ctx.Load(taxgroup.TermSets);
                ctx.ExecuteQuery();

                foreach (var termset in taxgroup.TermSets)
                {
                    string fileContents = header + "\n";
                    var terms = termset.GetAllTerms();
                    ctx.Load(terms);
                    ctx.ExecuteQuery();
                    foreach (var term in terms)
                    {
                        fileContents += String.Format("{0},{1},,{2},{3},{4},,,,,,,", termset.Name, termset.Description,
                                                    termset.IsAvailableForTagging, term.Description,
                                                    term.Name) + "\n";
                        ctx.Load(term.Terms);
                        ctx.ExecuteQuery();
                        foreach (var subTerm in term.Terms)
                        {
                            ExportTerm(ref fileContents, subTerm, String.Format("{0}", term.Name), ref ctx);
                        }
                    }
                    if (!System.IO.Directory.Exists(Directory + "/" + taxgroup.Name)) System.IO.Directory.CreateDirectory(Directory + "/" + taxgroup.Name);
                    System.IO.File.WriteAllText(Directory + "/" + taxgroup.Name + "/" + termset.Name + ".csv", fileContents);
                }

            }


            base.ProcessRecord();
        }

        public void ExportTerm(ref string data, Term subTerm, string heritage, ref ClientContext ctx)
        {
            heritage = String.Concat(heritage, ",", String.Format("{0}", subTerm.Name));
            data += String.Format(",,,{0},{1},{2}", subTerm.IsAvailableForTagging, subTerm.Description, heritage) + "\n";
            ctx.Load(subTerm.Terms);
            ctx.ExecuteQuery();
            foreach (var subSubTerm in subTerm.Terms)
            {
                ExportTerm(ref data, subSubTerm, heritage, ref ctx);
            }
        }
    }
}
